#include "typedef.h"

//exception numbers
#define         DIVIDE_ERROR            0
#define         DEBUG_EXCEPTION         1
#define         BREAKPOINT              3
#define         OVERFLOW                4
#define         BOUNDS_CHECK            5
#define         INVALID_OPCODE          6 
#define         NO_COPROCESSOR          7
#define         DOUBLE_FAULT            8
#define         COPROCESSOR_OVERRUN     9
#define         INVALID_TSS             10
#define         SEGMENT_MISSING         11
#define         STACK_EXCEPTION         12
#define         TRIPLE_FAULT            13
#define         PAGE_FAULT              14
#define         CORPROCESSOR_ERROR      16

//irq numbers
#define         TIMER_IRQ               32
#define         KBD_IRQ                 33
#define         FLOPPY_IRQ              38
 

#define		MAX_INTERRUPTS		256
#define		INTERRUPT_FLAGS		0x8E


struct idt_entry {
	word base_lo;
	word selector;
	byte zero;
	byte flags;
	word base_hi;
} __attribute__((packed));

typedef struct idt_entry IDT_entry;

struct _IDTR {
	word limit;
	dword offset;
} __attribute__((packed));

typedef struct _IDTR IDTR;

IDT_entry idt[MAX_INTERRUPTS];


/* this is a structure containing all the data pushed on the
 * stack as a result of an interrupt happening. */
typedef struct {
	dword ds; 				// Data segment selector
	dword edi, esi, ebp, esp, ebx, edx, ecx, eax; 	// Pushed by pusha.
	dword int_no, err_code;	 	// Interrupt number and error code (if applicable)
	dword eip, cs, eflags, useresp, ss; 	// Pushed by the processor automatically.
} registers; 



typedef void (*interrupt_t)();


/* defined in idt.s */
extern void load_IDT(u32);


/* install an isr into the idt */
void install_handler(int, dword);

/* this actually changes the function which the interrupt executes */
void register_isr(int, interrupt_t);

/* entry function that calls the appropriate interrupt. this should
 * only be called from the isr stub */
void handle_interrupt(registers);

/* initializes interrupt table */
void init_interrupts(void);


/* here are references to all the isr stubs that are defined in isr_stubs.s */
extern void isr_stub_0();
extern void isr_stub_1();
extern void isr_stub_2();
extern void isr_stub_3();
extern void isr_stub_4();
extern void isr_stub_5();
extern void isr_stub_6();
extern void isr_stub_7();
extern void isr_stub_8();
extern void isr_stub_9();
extern void isr_stub_10();
extern void isr_stub_11();
extern void isr_stub_12();
extern void isr_stub_13();
extern void isr_stub_14();
extern void isr_stub_15();
extern void isr_stub_16();
extern void isr_stub_17();
extern void isr_stub_18();
extern void isr_stub_19();
extern void isr_stub_20();
extern void isr_stub_21();
extern void isr_stub_22();
extern void isr_stub_23();
extern void isr_stub_24();
extern void isr_stub_25();
extern void isr_stub_26();
extern void isr_stub_27();
extern void isr_stub_28();
extern void isr_stub_29();
extern void isr_stub_30();
extern void isr_stub_31();
extern void isr_stub_32();
extern void isr_stub_33();
extern void isr_stub_34();
extern void isr_stub_35();
extern void isr_stub_36();
extern void isr_stub_37();
extern void isr_stub_38();
extern void isr_stub_39();
extern void isr_stub_40();
extern void isr_stub_41();
extern void isr_stub_42();
extern void isr_stub_43();
extern void isr_stub_44();
extern void isr_stub_45();
extern void isr_stub_46();
extern void isr_stub_47();

